package cn.edu.cug.cs.gtl.docsrv.img.dao.impl;


import cn.edu.cug.cs.gtl.docsrv.Managers;
import cn.edu.cug.cs.gtl.docsrv.img.dao.ImgDao;
import cn.edu.cug.cs.gtl.docsrv.img.block.ImageBlock;
import cn.edu.cug.cs.gtl.docsrv.img.catalog.CatalogTree;
import cn.edu.cug.cs.gtl.docsrv.img.manager.ImgManager;
import cn.edu.cug.cs.gtl.docsrv.img.querier.BlockQuerier;  
import cn.edu.cug.cs.gtl.mybatis.mapper.img.ImgAll;
import cn.edu.cug.cs.gtl.mybatis.mapper.img.ImgCatalog;
import cn.edu.cug.cs.gtl.mybatis.metadata.ImgUtils;
import cn.edu.cug.cs.gtl.protos.Document;
import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geojson.geom.GeometryJSON;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;
import org.opengis.feature.Feature;
import org.opengis.feature.simple.SimpleFeature;
import org.springframework.stereotype.Component;


import java.awt.image.BufferedImage; 
import java.math.BigDecimal;
import java.util.*;

@Component
public class ImgDaoImpl implements ImgDao {
    ImgManager imgManager =null;

    public ImgDaoImpl() {
        super();
    }

    /** 
     * 服务名称：addImg
     * 功能描述：单个本地Img文件入库
     * 接口描述： /api/img/addImg
     * 传入参数：
     * ImgAll  img；前端传入ImgAll的JSON对象
     * 返回值：
     * 成功返回true , 否则返回false
     * 调用示例：
     *
     * @param imgAll
     */
    @Override
    public void addImg(ImgAll imgAll) {
        if(imgManager==null)
            imgManager= Managers.getImgManager();
        imgManager.insert(imgAll);
    }

    /** 
     * 服务名称：addImgs
     * 功能描述：多个本地IMG文件入库
     * 接口描述： /api/img/ addImgs
     * 传入参数：
     * List<ImgAll>  imgs；前端传入ImgAll列表的JSON对象
     * 返回值：
     * 成功返回true , 否则返回false
     * 调用示例：
     *
     * @param ls
     */
    @Override
    public void addImgs(List<ImgAll> ls) {
        if(ls==null || ls.size()==0)
            return;
        for(ImgAll imgAll: ls)
            addImg(imgAll);
    }

    /** 
     * 服务名称：addFromRawDB
     * 功能描述：从原始数据库中提取指定类型的图像文件入库
     * 接口描述： /api/img/addFromRawDB
     * 传入参数：
     * String imgType   图像类型，文件后缀；
     * 返回值：
     * 成功返回true , 否则返回false
     * 调用示例：
     */
    @Deprecated
    @Override
    public boolean addFromRawDB() {
        return false;
    }

    /** 
     * 服务名称：getImgByName
     * 功能描述：图像数据库中提取指定名称的图像文件
     * 接口描述： /api/img/getImgByName
     * 传入参数：
     * String imgName   图像名称；
     * 返回值：
     * List<ImgAll> imgAllList 的JSON字符串
     * 调用示例：
     *
     * @param imgName
     */
    @Override
    public List<ImgAll> getImgByName(String imgName) {
        return getImgByEnTitle(imgName);
    }

    /** 
     * 服务名称：getImgByEnTitle
     * 功能描述：图像数据库中提取指定英文名称的图像文件
     * 接口描述： /api/img/ getImgByEnTitle
     * 传入参数：
     * String enTitle ；
     * 返回值：
     * List<ImgAll> imgAllList 的JSON字符串
     * 调用示例：
     *
     * @param enTitle
     */
    @Override
    public List<ImgAll> getImgByEnTitle(String enTitle) {
        if(imgManager==null)
            imgManager=Managers.getImgManager();
        return imgManager.queryByEnTitle(enTitle);
    }

    /** 
     * 服务名称：getImgByCnTitle
     * 功能描述：图像数据库中提取指定中文名称的图像文件
     * 接口描述： /api/img/ getImgByCnTitle
     * 传入参数：
     * String cnTitle ；
     * 返回值：
     * List<ImgAll> imgAllList 的JSON字符串
     * 调用示例：
     *
     * @param cnTitle
     */
    @Override
    public List<ImgAll> getImgByCnTitle(String cnTitle) {
        if(imgManager==null)
            imgManager=Managers.getImgManager();
        return imgManager.queryByComment(cnTitle);
    }

    /** 
     * 服务名称：getImgByInternalId
     * 功能描述：图像数据库中提取指定ID的图像文件
     * 接口描述： /api/img/getImgByInternalId
     * 传入参数：
     * long internalId；
     * 返回值：
     * ImgAll  img     ; ImgAll的JSON字符串
     * 调用示例：
     *
     * @param internalId
     */
    @Override
    public ImgAll getImgByInternalId(BigDecimal internalId) {
        if(imgManager==null)
            imgManager=Managers.getImgManager();
        ImgAll imgAll = imgManager.queryByInternalId(internalId);
        return imgAll;
    }

    /** 
     * 服务名称：getImgByBoundingBox
     * 功能描述：图像数据库中提取指定范围的图像
     * 接口描述： /api/img/getImgByBoundingBox
     * 传入参数：
     *      String bb；//minx,maxx,miny,maxy  数字之间逗号分隔
     *      String mask; //intersect 相交的图像； 或  contains 包含的图像
     * 返回值：
     * List<ImgAll> imgAllList 的JSON字符串
     * 调用示例：
     *
     * @param g
     * @param mask
     */
    @Override
    public List<ImgAll> getImgByBoundingBox(Geometry g, String mask) {
        if(imgManager==null)
            imgManager=Managers.getImgManager();
        BlockQuerier bq = imgManager.getBlockQuerier();
        List<ImgAll> imgAllList = new ArrayList<>();
        if("intersect".equals(mask)) {
            if (bq.intersects(g)) {
                Iterator<ImageBlock> imageBlockIterator = bq.iterator();
                while (imageBlockIterator.hasNext())
                    imgAllList.add(imageBlockIterator.next().getImgAll());
            }
        }
        else{
            if (bq.contains(g)) {
                Iterator<ImageBlock> imageBlockIterator = bq.iterator();
                while (imageBlockIterator.hasNext())
                    imgAllList.add(imageBlockIterator.next().getImgAll());
            }
        }
        return imgAllList;
    }

    /**
     * 服务名称：deleteImgByInternalId
     * 功能描述：删除图像数据库中指定ID的图像
     * 接口描述： /api/img/deleteImgByInternalId
     * 传入参数：
     * long internalId；
     * 返回值：
     * 成功返回true , 否则返回false
     * 调用示例：
     *
     * @param internalId
     */
    @Override
    public boolean deleteImgByInternalId(BigDecimal internalId) {
        if(imgManager==null)
            imgManager=Managers.getImgManager();
        ImgAll imgAll =new ImgAll();
        imgAll.setImgInternalId(internalId);
        return imgManager.delete(imgAll);
    }

    /**
     * 服务名称：getImageByImgInternalId
     * 功能描述：图像数据库中提取指定Img的几何对象
     * 接口描述： /api/img/getImageByImgInternalId
     * 传入参数：
     * long imgInternalId
     * 返回值：
     * GeometryJSON的列表
     * 调用示例：
     *
     * @param imgInternalId
     */
    @Override
    public BufferedImage getImageByImgInternalId(BigDecimal imgInternalId) {
        return null;
    }

    /**
     * 服务名称：getEnvelopeByImgInternalId
     * 功能描述：图像数据库中提取指定范围的几何对象
     * 接口描述： /api/img/getEnvelopeByImgInternalId
     * 传入参数：
     * long imgInternalId
     * 返回值：
     * Envelope
     * 调用示例：
     *
     * @param imgInternalId
     */
    @Override
    public Envelope getEnvelopeByImgInternalId(BigDecimal imgInternalId) {
        if(imgManager==null)
            imgManager=Managers.getImgManager();
        return null;
    }

    /**
     * 服务名称：getImgCatalogs
     * 功能描述：图像数据库中提取所有分类
     * 接口描述： /api/img/getImgCatalogs
     * 传入参数：
     * 返回值：
     * List<ImgCatalog> catalogs
     * 调用示例：
     */
    @Override
    public List<ImgCatalog> getImgCatalogs() {
        if(imgManager==null)
            imgManager=Managers.getImgManager();
        return imgManager.getCatalogs();
    }

    /**
     * 服务名称：getDocumentByImgInternalId
     * 功能描述：图像数据库中提取指定Img文档
     * 接口描述： /api/img/getDocumentByImgInternalId
     * 传入参数：
     * long imgInternalId
     * 返回值：
     * Document doc;
     * 其中，每个Feature的GeoJSON字符串为Document的一个content；
     * 其他的不为空的字段为该Img文档的元数据。
     * 调用示例：
     * http://localhost:8090/api/img/getDocumentByImgInternalId?imgInternalId=3
     *
     * @param imgInternalId
     */
    @Override
    public Document getDocumentByImgInternalId(BigDecimal imgInternalId) {
        return null;
    }


    @Override
    public List<ImgAll> getImgByCatalogInternalId(BigDecimal catalogInternalId) {
        if(imgManager==null)
            imgManager=Managers.getImgManager();
        try {
            Map<String,Object> p = new LinkedHashMap<String,Object>();
            p.put("imgCatalog",catalogInternalId);
            List<ImgAll> imgAllList = imgManager.query(p);
            return imgAllList;
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将所有的目录整理成一个树后返回
     *
     * @return
     */
    @Override
    public CatalogTree getCatalogTree() {
        if(imgManager==null)
            imgManager=Managers.getImgManager();
        return imgManager.getCatalogTree();
    }

    @Override
    public List<BigDecimal> getImgInternalIdsByCatalogInternalId(BigDecimal catalogId) {
        if(imgManager==null)
            imgManager=Managers.getImgManager();
        return imgManager.getImgInternalIdsByCatalogInternalId(catalogId);
    }

}

